﻿/*
 * Author: XYZ.SEAN.M.THX 
 * Email: seanmpthx@gmail.com
 * Copyright: (c) 2010-2020
 * Version:0.1
 * 
 * <Update>
 *   创建于 2012-07-4
 * </Update>
 * <Remark>
 * 
 * </Remark>
*/
using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;

namespace XYZShell.CsHelper
{
    /// <summary>
    /// 加解密相干帮助函数
    /// </summary>
    public class SecurityHelper
    {
        /// <summary>
        /// 得到密文
        /// </summary>
        /// <param name="text">源文</param>
        /// <param name="Format">加密格式（MD5,SHA1……）</param>
        /// <returns></returns>
        public static string GetCiphertext(string text, string Format)
        {
            if (Format == null)
            {
                throw new ArgumentNullException("Format");
            }
            if (text == null)
            {
                throw new ArgumentNullException("text");
            }
            HashAlgorithm alorithm;
            if (Format.Equals("sha1", StringComparison.OrdinalIgnoreCase))
            {
                alorithm = HashAlgorithm.Create("SHA1");
            }
            else if (Format.Equals("md5", StringComparison.OrdinalIgnoreCase))
            {
                alorithm = HashAlgorithm.Create("MD5");
            }
            else
            {
                alorithm = HashAlgorithm.Create(Format); 
            }
            byte[] bt = alorithm.ComputeHash(UTF8Encoding.Default.GetBytes(text));
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < bt.Length; i++)
            {
                sb.Append(bt[i].ToString("x").PadLeft(2, '0'));
            }
            return sb.ToString();
        }
        /// <summary>
        /// md5加密
        /// </summary>
        /// <param name="text">源文</param>
        /// <returns></returns>
        public static string MD5(string text)
        {
            return GetCiphertext(text, "md5");
        }
        /// <summary>
        /// sha1加密
        /// </summary>
        /// <param name="text">源文</param>
        /// <returns></returns>
        public static string SHA1(string text)
        {
            return GetCiphertext(text, "sha1");
        }
        /// <summary>
        /// 加密
        /// </summary>
        /// <param name="key">密匙</param>
        /// <param name="value">原文</param>
        /// <param name="_Iv">加密向量</param>
        /// <returns></returns>
        public static string Md5Encrypt(string key, string value, string _Iv)
        {
            DESCryptoServiceProvider dsp = new DESCryptoServiceProvider();
            byte[] inputBytes = Encoding.Default.GetBytes(value);
            dsp.Key = Encoding.Default.GetBytes(MD5(key).Substring(0, 8));
            dsp.IV = Encoding.Default.GetBytes(MD5(_Iv).Substring(0, 8));
            System.IO.MemoryStream ms = new System.IO.MemoryStream();
            CryptoStream cs = new CryptoStream(ms, dsp.CreateEncryptor(), CryptoStreamMode.Write);
            cs.Write(inputBytes, 0, inputBytes.Length);
            cs.FlushFinalBlock();
            StringBuilder ret = new StringBuilder();
            foreach (byte b in ms.ToArray())
            {
                ret.AppendFormat("{0:X2}", b);
            }
            return ret.ToString();
        }

        /// <summary>
        /// 解密
        /// </summary>
        /// <param name="Text">密文</param>
        /// <param name="sKey">密匙</param>
        /// <param name="_Iv">加密向量</param>
        /// <returns></returns>
        public static string Md5Decrypt(string Text, string sKey, string _Iv)
        {
            DESCryptoServiceProvider dsp = new DESCryptoServiceProvider();
            int len = Text.Length / 2;
            byte[] inputBytes = new byte[len];
            int x, i;
            for (x = 0; x < len; x++)
            {
                i = Convert.ToInt32(Text.Substring(x * 2, 2), 16);
                inputBytes[x] = (byte)i;
            }
            dsp.Key = Encoding.Default.GetBytes(MD5(sKey).Substring(0, 8));
            dsp.IV = Encoding.Default.GetBytes(MD5(_Iv).Substring(0, 8));
            System.IO.MemoryStream ms = new System.IO.MemoryStream();
            CryptoStream cs = new CryptoStream(ms, dsp.CreateDecryptor(), CryptoStreamMode.Write);
            cs.Write(inputBytes, 0, inputBytes.Length);
            cs.FlushFinalBlock();
            return Encoding.Default.GetString(ms.ToArray());
        }


        /// <summary>
        ///  TripleDES加密
        /// </summary>
        /// <param name="strSource">原文</param>
        /// <param name="_key">密匙</param>
        /// <param name="_IV">加密向量</param>
        /// <returns></returns>
        public static string TripleDESEncrypting(string strSource, byte[] _key, byte[] _IV)
        {
            try
            {
                byte[] bytIn = Encoding.Default.GetBytes(strSource);
                byte[] key = _key;
                byte[] IV = _IV;
                TripleDESCryptoServiceProvider TripleDES = new TripleDESCryptoServiceProvider();
                TripleDES.IV = IV;
                TripleDES.Key = key;
                ICryptoTransform encrypto = TripleDES.CreateEncryptor();
                System.IO.MemoryStream ms = new System.IO.MemoryStream();
                CryptoStream cs = new CryptoStream(ms, encrypto, CryptoStreamMode.Write);
                cs.Write(bytIn, 0, bytIn.Length);
                cs.FlushFinalBlock();
                byte[] bytOut = ms.ToArray();
                return System.Convert.ToBase64String(bytOut);
            }
            catch (Exception ex)
            {
                throw new Exception("加密时候出现错误!错误提示:\n" + ex.Message);
            }
        }

        /// <summary>
        ///  TripleDES解密
        /// </summary>
        /// <param name="Source">密文</param>
        /// <param name="_key">密匙</param>
        /// <param name="_IV">加密向量</param>
        /// <returns></returns>
        public static string TripleDESDecrypting(string Source, byte[] _key, byte[] _IV)
        {
            try
            {
                byte[] bytIn = System.Convert.FromBase64String(Source);
                byte[] key = _key;
                byte[] IV = _IV;
                TripleDESCryptoServiceProvider TripleDES = new TripleDESCryptoServiceProvider();
                TripleDES.IV = IV;
                TripleDES.Key = key;
                ICryptoTransform encrypto = TripleDES.CreateDecryptor();
                System.IO.MemoryStream ms = new System.IO.MemoryStream(bytIn, 0, bytIn.Length);
                CryptoStream cs = new CryptoStream(ms, encrypto, CryptoStreamMode.Read);
                StreamReader strd = new StreamReader(cs, Encoding.Default);
                return strd.ReadToEnd();
            }
            catch (Exception ex)
            {
                throw new Exception("解密时候出现错误!错误提示:\n" + ex.Message);
            }
        }
    }
}
